package cn.tlb.gl.game.head;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.opengl.Matrix;
import android.os.Bundle;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import cn.tlb.BaseGLActivity;
import cn.tlb.xutilsdownload.R;

public class CubeHeadActivity extends BaseGLActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mGlSurfaceView.setRenderer(new CubeRenderer());
        setContentView(mGlSurfaceView);
    }

    class CubeRenderer implements GLSurfaceView.Renderer{

        /**人物头部尺寸, 以此作为标准, 头像纹理占8个像素,取值为1,由此计算比例*/
        private static final float HEAD_SIZE = .5f;
        private static final float unit = HEAD_SIZE/8;
        //将偷的几何中心置于原点, 取一半计算坐标
        private static final float head = HEAD_SIZE/2;
        // 帽子和头部间距0.5像素
        private static final float cap_space = unit/2;

        ///////////////////////////////////////////////////////////////////////////
        // 人物头部
        ///////////////////////////////////////////////////////////////////////////
        FloatBuffer topBuffer = array2FloatBuffer(new float[]{
                -head,  head,   -head,  // 0,0
                -head,  head,    head,   // 0,1
                 head,  head,   -head, // 1,0
                -head,  head,    head,   // 0,1
                 head,  head,   -head, // 1,0
                 head,  head,    head,  // 1,1
        });

        FloatBuffer bottomBuffer = array2FloatBuffer(new float[]{
                -head,  -head,  head,  // 0,0
                -head,  -head,  -head,   // 0,1
                head,   -head,  head, // 1,0
                -head,  -head,  -head,   // 0,1
                head,   -head,  head, // 1,0
                head,   -head,  -head,  // 1,1
        });

        FloatBuffer frontBuffer = array2FloatBuffer(new float[]{
                -head,  head,   head,  // 0,0
                -head,  -head,  head,   // 0,1
                head,   head,   head, // 1,0
                -head,  -head,  head,   // 0,1
                head,   head,   head, // 1,0
                head,   -head,  head,  // 1,1
        });

        FloatBuffer backBuffer = array2FloatBuffer(new float[]{
                -head,  head,   -head,  // 0,0
                -head,  -head,  -head,   // 0,1
                head,   head,   -head, // 1,0
                -head,  -head,  -head,   // 0,1
                head,   head,   -head, // 1,0
                head,   -head,  -head,  // 1,1
        });

        FloatBuffer leftBuffer = array2FloatBuffer(new float[]{
                -head,  head,   -head,
                -head,  -head,  -head,
                -head,  head,   head,
                -head,  -head,  -head,
                -head,  head,   head,
                -head,  -head,  head,
        });

        FloatBuffer rightBuffer = array2FloatBuffer(new float[]{
                head,   head,   head,
                head,   -head,  head,
                head,   head,   -head,
                head,   -head,  head,
                head,   head,   -head,
                head,   -head,  -head,
        });

        ///////////////////////////////////////////////////////////////////////////
        // 人物帽子
        ///////////////////////////////////////////////////////////////////////////
        private static final float cap = head+cap_space;
        FloatBuffer cap_top = array2FloatBuffer(new float[]{
                -cap, cap, -cap,
                -cap, cap, cap,
                cap, cap, -cap,
                -cap, cap, cap,
                cap, cap, -cap,
                cap, cap, cap,
        });

        FloatBuffer cap_bottom = array2FloatBuffer(new float[]{
                -cap, -cap, cap,
                -cap, -cap, -cap,
                cap, -cap, cap,
                -cap, -cap, -cap,
                cap, -cap, cap,
                cap, -cap, -cap,
        });

        FloatBuffer cap_front = array2FloatBuffer(new float[]{
                -cap, cap, cap,
                -cap, -cap, cap,
                cap, cap, cap,
                -cap, -cap, cap,
                cap, cap, cap,
                cap, -cap, cap,
        });

        FloatBuffer cap_back = array2FloatBuffer(new float[]{
                -cap, cap, -cap,
                -cap, -cap, -cap,
                cap, cap, -cap,
                -cap, -cap, -cap,
                cap, cap, -cap,
                cap, -cap, -cap,
        });

        FloatBuffer cap_left = array2FloatBuffer(new float[]{
                -cap, cap, -cap,
                -cap, -cap, -cap,
                -cap, cap, cap,
                -cap, -cap, -cap,
                -cap, cap, cap,
                -cap, -cap, cap,
        });

        FloatBuffer cap_right = array2FloatBuffer(new float[]{
                cap, cap, cap,
                cap, -cap, cap,
                cap, cap, -cap,
                cap, -cap, cap,
                cap, cap, -cap,
                cap, -cap, -cap,
        });
        ///////////////////////////////////////////////////////////////////////////
        // arm
        ///////////////////////////////////////////////////////////////////////////
        private static final float arm = head/2;
        private static final float arm_length = 3*arm;
        private static final float left_arm_x = 0 - 3*head/2;
        private static final float left_arm_y = 0 - 5*head/2;

        FloatBuffer left_arm_top = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
        });

        FloatBuffer left_arm_bottom = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_left = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_right = array2FloatBuffer(new float[]{
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_front = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x - arm, left_arm_y - arm_length, arm,
                left_arm_x + arm, left_arm_y + arm_length, arm,
                left_arm_x + arm, left_arm_y - arm_length, arm,
        });

        FloatBuffer left_arm_back = array2FloatBuffer(new float[]{
                left_arm_x - arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x - arm, left_arm_y - arm_length, -arm,
                left_arm_x + arm, left_arm_y + arm_length, -arm,
                left_arm_x + arm, left_arm_y - arm_length, -arm,
        });

        private static final float right_arm_x = 0 + 3*head/2;
        private static final float right_arm_y = 0 - 5*head/2;
        // left -> right
        FloatBuffer right_arm_top = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
        });

        FloatBuffer right_arm_bottom = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_left = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_right = array2FloatBuffer(new float[]{
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_front = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x - arm, right_arm_y - arm_length, arm,
                right_arm_x + arm, right_arm_y + arm_length, arm,
                right_arm_x + arm, right_arm_y - arm_length, arm,
        });

        FloatBuffer right_arm_back = array2FloatBuffer(new float[]{
                right_arm_x - arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x - arm, right_arm_y - arm_length, -arm,
                right_arm_x + arm, right_arm_y + arm_length, -arm,
                right_arm_x + arm, right_arm_y - arm_length, -arm,
        });

        ///////////////////////////////////////////////////////////////////////////
        // body
        ///////////////////////////////////////////////////////////////////////////
        private static final float body_x = 0;
        private static final float body_y = 0 - 5*head/2;
        private static final float body_length = head;//长
        private static final float body_width = arm;//宽
        private static final float body_height = arm_length;//高

        FloatBuffer body_top = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x + body_length, body_y + body_height, body_width,
        });

        FloatBuffer body_bottom = array2FloatBuffer(new float[]{
                body_x - body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_left = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x - body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_right = array2FloatBuffer(new float[]{
                body_x + body_length, body_y + body_height, -body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x + body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x + body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_front = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x - body_length, body_y - body_height, body_width,
                body_x + body_length, body_y + body_height, body_width,
                body_x + body_length, body_y - body_height, body_width,
        });

        FloatBuffer body_back = array2FloatBuffer(new float[]{
                body_x - body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x - body_length, body_y - body_height, -body_width,
                body_x + body_length, body_y + body_height, -body_width,
                body_x + body_length, body_y - body_height, -body_width,
        });

        ///////////////////////////////////////////////////////////////////////////
        // legs
        ///////////////////////////////////////////////////////////////////////////
        private static final float leg = head/2;
        private static final float leg_length = 3*leg;
        private static final float left_leg_x = 0 /*- head/2*/;
        private static final float left_leg_y = 0 /*- 5*head*/;
        private static final float debug_left_leg_x = 0 - head/2;
        private static final float debug_left_leg_y = 0 - 5*head;

        FloatBuffer left_leg_top = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
        });

        FloatBuffer left_leg_bottom = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_left = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_right = array2FloatBuffer(new float[]{
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_front = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x - leg, left_leg_y - leg_length, leg,
                left_leg_x + leg, left_leg_y + leg_length, leg,
                left_leg_x + leg, left_leg_y - leg_length, leg,
        });

        FloatBuffer left_leg_back = array2FloatBuffer(new float[]{
                left_leg_x - leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x - leg, left_leg_y - leg_length, -leg,
                left_leg_x + leg, left_leg_y + leg_length, -leg,
                left_leg_x + leg, left_leg_y - leg_length, -leg,
        });

        private static final float right_leg_x = 0 /*+ head/2*/;
        private static final float right_leg_y = 0 /*- 5*head*/;
        private static final float debug_right_leg_x = 0 + head/2;
        private static final float debug_right_leg_y = 0 - 5*head;
        // left -> right
        FloatBuffer right_leg_top = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
        });

        FloatBuffer right_leg_bottom = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_left = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_right = array2FloatBuffer(new float[]{
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_front = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x - leg, right_leg_y - leg_length, leg,
                right_leg_x + leg, right_leg_y + leg_length, leg,
                right_leg_x + leg, right_leg_y - leg_length, leg,
        });

        FloatBuffer right_leg_back = array2FloatBuffer(new float[]{
                right_leg_x - leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x - leg, right_leg_y - leg_length, -leg,
                right_leg_x + leg, right_leg_y + leg_length, -leg,
                right_leg_x + leg, right_leg_y - leg_length, -leg,
        });


        //顶点index
        ByteBuffer indexBuffer = ByteBuffer.wrap(new byte[]{0, 1, 2, 3, 4, 5});

        //纹理坐标
        FloatBuffer textBuffer = array2FloatBuffer(new float[]{
                0,0,    0,1,    1,0,
                0,1,    1,0,    1,1
        });

        @Override
        public void onSurfaceCreated(GL10 gl, EGLConfig config) {
            gl.glDisable(GL10.GL_DITHER);
            gl.glShadeModel(GL10.GL_SMOOTH);

            gl.glClearColor(0, 0, 0, 0);
            gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
            gl.glEnable(GL10.GL_DEPTH_TEST);
            gl.glDepthFunc(GL10.GL_LEQUAL);

            //启用2d纹理贴图
            gl.glEnable(GL10.GL_TEXTURE_2D);
            loadTexture(gl);

            //启用opengl混合, 详见 http://dxwang.blog.51cto.com/384651/693834
            gl.glEnable(GL10.GL_BLEND);
            gl.glBlendFunc(GL10.GL_SRC_ALPHA, GL10.GL_ONE_MINUS_SRC_ALPHA);
        }

        private static final int index_head_top = 0;
        private static final int index_head_front = 1;
        private static final int index_head_left = 2;
        private static final int index_head_right = 3;
        private static final int index_head_back = 4;
        private static final int index_head_bottom = 5;
        private static final int index_cap_top = 6;
        private static final int index_cap_front = 7;
        private static final int index_cap_left = 8;
        private static final int index_cap_right = 9;
        private static final int index_cap_back = 10;
        private static final int index_cap_bottom = 11;
        private static final int index_left_arm_top = 12;
        private static final int index_left_arm_front = 13;
        private static final int index_left_arm_left = 14;
        private static final int index_left_arm_right = 15;
        private static final int index_left_arm_back = 16;
        private static final int index_left_arm_bottom = 17;
        private static final int index_body_top = 18;
        private static final int index_body_front = 19;
        private static final int index_body_left = 20;
        private static final int index_body_right = 21;
        private static final int index_body_back = 22;
        private static final int index_body_bottom = 23;
        private static final int index_left_leg_top = 24;
        private static final int index_left_leg_front = 25;
        private static final int index_left_leg_left = 26;
        private static final int index_left_leg_right = 27;
        private static final int index_left_leg_back = 28;
        private static final int index_left_leg_bottom = 29;
        int[] ids = {
                R.drawable.head_top, R.drawable.head_front,R.drawable.head_left,
                R.drawable.head_right,R.drawable.head_back,R.drawable.head_bottom,
                R.drawable.cap_top, R.drawable.cap_front, R.drawable.cap_left,
                R.drawable.cap_right,R.drawable.cap_back,R.drawable.cap_bottom,
                R.drawable.left_arm_top, R.drawable.left_arm_front, R.drawable.left_arm_left,
                R.drawable.left_arm_right,R.drawable.left_arm_back,R.drawable.left_arm_bottom,
                R.drawable.body_top, R.drawable.body_front,R.drawable.body_left,
                R.drawable.body_right,R.drawable.body_back,R.drawable.body_bottom,
                R.drawable.left_leg_top, R.drawable.left_leg_front, R.drawable.left_leg_left,
                R.drawable.left_leg_right,R.drawable.left_leg_back,R.drawable.left_leg_bottom,
        };
        int[] textures = new int[ids.length];

        private void loadTexture(GL10 gl) {
            gl.glGenTextures(textures.length, textures, 0);
            for (int i = 0; i < textures.length; i++) {
                Bitmap bitmap = BitmapFactory.decodeResource(getResources(), ids[i]);
                //在为纹理提供图像数据之前，我们必须绑定纹理
                gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[i]);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
                // TODO 此处原设为 GL_LINEAR 然游戏图片中显示为像素点即可,也就是不使用插值, 因而选用 GL_NEAREST
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_NEAREST);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
                gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
                GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

                bitmap.recycle();
                bitmap = null;
            }
        }

        @Override
        public void onSurfaceChanged(GL10 gl, int width, int height) {
            gl.glViewport(0, 0, width, height);
            gl.glMatrixMode(GL10.GL_PROJECTION);
            gl.glLoadIdentity();
            float ratio = (float)width/height;
            float y = 1;
            gl.glFrustumf(-ratio*y, ratio*y, -y - y/2, y - y/2, 1, 20);
        }

        @Override
        public void onDrawFrame(GL10 gl) {
            gl.glClear(GL10.GL_DEPTH_BUFFER_BIT | GL10.GL_COLOR_BUFFER_BIT);
            gl.glMatrixMode(GL10.GL_MODELVIEW);

            gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            drawFace(gl, topBuffer, textures[index_head_top]);
            drawFace(gl, bottomBuffer, textures[index_head_bottom]);
            drawFace(gl, leftBuffer, textures[index_head_left]);
            drawFace(gl, rightBuffer, textures[index_head_right]);
            drawFace(gl, frontBuffer, textures[index_head_front]);
            drawFace(gl, backBuffer, textures[index_head_back]);

            drawFace(gl, cap_top, textures[index_cap_top]);
            drawFace(gl, cap_bottom, textures[index_cap_bottom]);
            drawFace(gl, cap_left, textures[index_cap_left]);
            drawFace(gl, cap_right, textures[index_cap_right]);
            drawFace(gl, cap_front, textures[index_cap_front]);
            drawFace(gl, cap_back, textures[index_cap_back]);

            drawLeftArm(gl, left_arm_top, textures[index_left_arm_top]);
            drawLeftArm(gl, left_arm_bottom, textures[index_left_arm_bottom]);
            drawLeftArm(gl, left_arm_left, textures[index_left_arm_left]);
            drawLeftArm(gl, left_arm_right, textures[index_left_arm_right]);
            drawLeftArm(gl, left_arm_front, textures[index_left_arm_front]);
            drawLeftArm(gl, left_arm_back, textures[index_left_arm_back]);

            drawRightArm(gl, right_arm_top, textures[index_left_arm_top]);
            drawRightArm(gl, right_arm_bottom, textures[index_left_arm_bottom]);
            drawRightArm(gl, right_arm_left, textures[index_left_arm_left]);
            drawRightArm(gl, right_arm_right, textures[index_left_arm_right]);
            drawRightArm(gl, right_arm_front, textures[index_left_arm_front]);
            drawRightArm(gl, right_arm_back, textures[index_left_arm_back]);

            drawBody(gl, body_top, textures[index_body_top]);
            drawBody(gl, body_bottom, textures[index_body_bottom]);
            drawBody(gl, body_left, textures[index_body_left]);
            drawBody(gl, body_right, textures[index_body_right]);
            drawBody(gl, body_front, textures[index_body_front]);
            drawBody(gl, body_back, textures[index_body_back]);

            drawLeftLeg(gl, left_leg_top, textures[index_left_leg_top]);
            drawLeftLeg(gl, left_leg_bottom, textures[index_left_leg_bottom]);
            drawLeftLeg(gl, left_leg_left, textures[index_left_leg_left]);
            drawLeftLeg(gl, left_leg_right, textures[index_left_leg_right]);
            drawLeftLeg(gl, left_leg_front, textures[index_left_leg_front]);
            drawLeftLeg(gl, left_leg_back, textures[index_left_leg_back]);

            drawRightLeg(gl, right_leg_top, textures[index_left_leg_top]);
            drawRightLeg(gl, right_leg_bottom, textures[index_left_leg_bottom]);
            drawRightLeg(gl, right_leg_left, textures[index_left_leg_left]);
            drawRightLeg(gl, right_leg_right, textures[index_left_leg_right]);
            drawRightLeg(gl, right_leg_front, textures[index_left_leg_front]);
            drawRightLeg(gl, right_leg_back, textures[index_left_leg_back]);

            gl.glFinish();
            gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
            gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

            head_rotate_x += 0.2;
            head_rotate_y += 0.1;
            arm_rotate_x += 1;
            arm_rotate_y -=1;
        }

        private float[] m = new float[16];
        private void drawFace(GL10 gl, FloatBuffer vertex, int textureID) {
            gl.glLoadIdentity();
//            gl.glTranslatef(0, 0, -2);
//            gl.glRotatef(mAngleX, 0, 0.2f, 0);
//            gl.glRotatef(mAngleY, 0.2f, 0, 0);
//            //gl.glRotatef(head_rotate_x, 1, 0, 0);
            Matrix.setIdentityM(m, 0);
            Matrix.translateM(m, 0, 0, 0, -2);
            Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
            Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
            Matrix.rotateM(m, 0, f(head_rotate_x), 1, 0, 0);
            Matrix.rotateM(m, 0, f(head_rotate_y), 0, 1, 0);
            gl.glLoadMatrixf(m, 0);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
        }

        private void drawLeftArm(GL10 gl, FloatBuffer vertex, int textureID) {
            gl.glLoadIdentity();
            Matrix.setIdentityM(m, 0);
            Matrix.translateM(m, 0, 0, 0, -2);
            Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
            Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
            //Matrix.translateM(m, 0, -left_arm_x, -2*left_arm_y, 0);
            Matrix.rotateM(m, 0, g(arm_rotate_x), 1, 0, 0);
            //Matrix.translateM(m, 0, left_arm_x, -(-left_arm_y), 0);
            gl.glLoadMatrixf(m, 0);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
        }

        private void drawRightArm(GL10 gl, FloatBuffer vertex, int textureID) {
            gl.glLoadIdentity();
            Matrix.setIdentityM(m, 0);
            Matrix.translateM(m, 0, 0, 0, -2);
            Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
            Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
            //Matrix.translateM(m, 0, -right_arm_x, -2 * right_arm_y, 0);
            Matrix.rotateM(m, 0, -g(arm_rotate_x), 1, 0, 0);
            //Matrix.translateM(m, 0, right_arm_x, -(-right_arm_y), 0);
            gl.glLoadMatrixf(m, 0);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
        }

        private void drawBody(GL10 gl, FloatBuffer vertex, int textureID) {
            gl.glLoadIdentity();
            Matrix.setIdentityM(m, 0);
            Matrix.translateM(m, 0, 0, 0, -2);
            Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
            Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
            gl.glLoadMatrixf(m, 0);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);
        }

        private void drawLeftLeg(GL10 gl, FloatBuffer vertex, int textureID) {
            gl.glLoadIdentity();
//            Matrix.setIdentityM(m, 0);
//            Matrix.translateM(m, 0, 0, 0, -2);
//            Matrix.rotateM(m, 0, mAngleX, 0, 1, 0);
//            Matrix.rotateM(m, 0, mAngleY, 1, 0, 0);
//            Matrix.translateM(m, 0, 0, -left_leg_y, 0);
//            Matrix.rotateM(m, 0, g(arm_rotate_x), 1, 0, 0);
////            Matrix.translateM(m, 0, 0, left_leg_y, 0);
//            gl.glLoadMatrixf(m, 0);

            gl.glTranslatef(0, 0, -2);
            gl.glRotatef(mAngleX, 0, 1, 0);
            gl.glRotatef(mAngleY, 1, 0, 0);
            gl.glTranslatef(0, debug_left_leg_y / 4, 0);
            gl.glRotatef(-g(arm_rotate_x), 1, 0, 0);
            gl.glTranslatef(debug_left_leg_x, debug_left_leg_y - debug_left_leg_y / 4, 0);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);

        }

        private void drawRightLeg(GL10 gl, FloatBuffer vertex, int textureID) {
            gl.glLoadIdentity();
            gl.glTranslatef(0, 0, -2);
            gl.glRotatef(mAngleX, 0, 1, 0);
            gl.glRotatef(mAngleY, 1, 0, 0);
            gl.glTranslatef(0, debug_right_leg_y/4, 0);
            gl.glRotatef(g(arm_rotate_x), 1, 0, 0);
            gl.glTranslatef(debug_right_leg_x, debug_right_leg_y-debug_right_leg_y/4, 0);

            gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertex);
            gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textBuffer);
            gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
            gl.glDrawElements(GL10.GL_TRIANGLES, indexBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indexBuffer);

        }

        private float head_rotate_x;
        private float head_rotate_y;
        //头部扭动
        private float f(float x){
            x = x%40 - 10;// [-10, 30], 周期40
            // 函数 f(x) = -|x| 右移10,上移10
            return -Math.abs(x-10)+10;
        }

        private float arm_rotate_x;
        private float arm_rotate_y;
        // 四肢的摆动函数
        private float g(float x){
            x = x%80 - 20;
            return -Math.abs(x-20)+20;
        }
    }

    private static float sin(float degree){
        return (float) Math.sin(Math.toRadians(degree));
    }
    private static float cos(float degree){
        return (float) Math.cos(Math.toRadians(degree));
    }
}
